#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>

namespace ThreadModule
{
    template <class T>
    using func_t = std::function<void (T&)>;

    template <class T>
    class Thread
    {
    public:
        void Excute()
        {
            return _func(_data);//void _func(const T& _data)
        }
    public:
        Thread(func_t<T> func, T &data, const string threadname = "new thread")
            : _threadname(threadname), _tid(0), _data(data), _func(func), _stop(true)
        {
        }

        static void *threadroutine(void *args) // 类成员函数,第一个参数为this指针===> 为匹配参数,static修饰该函数
        {
            // return _func(_data);//static修饰的成员函数,没有this指针,无法访问类的私有成员
            //线程创建时利用参数传递this指针
            Thread<T>* self=(Thread<T>*)args;
            self->Excute();
            return nullptr;
        }
        bool Start()
        {
            int retval = pthread_create(&_tid, nullptr, threadroutine, this);
            if (retval == 0)
            {
                _stop = false;
                return true;
            }
            else
            {
                return false;
            }
        }
        void Join()
        {
            if (_stop != true)
            {
                pthread_join(_tid, nullptr);
            }
        }

        void Detach()
        {
            if (_stop != true)
            {
                pthread_detach(_tid);
            }
        }

        string threadname()
        {
            return _threadname;
        }

    private:
        std::string _threadname;
        pthread_t _tid;
        func_t<T> _func;
        T& _data;//保证各个线程访问同一个全局变量g_tickets;
        bool _stop;
    };
}